package com.example.baidusdk

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import com.baidu.mapapi.map.*
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener
import com.baidu.mapapi.map.InfoWindow.OnInfoWindowClickListener
import com.baidu.mapapi.model.LatLng

class MainActivity : AppCompatActivity() {

    //地图控件
    private var mMapView: MapView? = null

    //百度地图
    private var mBaiduMap: BaiduMap? = null

    //防止每次定位都重新设置中心点和marker
    private var isFirstLocation = true

    //初始化LocationClient定位类
    private var mLocationClient: LocationClient? = null

    //BDAbstractLocationListener为7.2版本新增的Abstract类型的监听接口
    private var myLocationListener = MyLocationListener(this)

    //经纬度
    var lat = 0.0
    var lon = 0.0

    //权限请求码
    private var mRuquestode = 1

    //请求的权限
    private var PERMISSION: Array<String> = arrayOf(
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.INTERNET,
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.READ_PHONE_STATE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    )

    fun clickMap() {
        val listener: OnMapClickListener = object : OnMapClickListener {
            /**
             * 地图单击事件回调函数
             *
             * @param point 点击的地理坐标
             */
            override fun onMapClick(point: LatLng) {
                var lat = lat.toString()
                var lon = lon.toString()
                Toast.makeText(
                    this@MainActivity,
                    lat + " , " + lon, Toast.LENGTH_SHORT
                ).show()
            }

            /**
             * 地图内 Poi 单击事件回调函数
             *
             * @param mapPoi 点击的 poi 信息
             */
            override fun onMapPoiClick(mapPoi: MapPoi) {}
        }
//设置地图单击事件监听
        mBaiduMap!!.setOnMapClickListener(listener)
    }

    fun addInfoWindow(lat: LatLng) {
        //用来构造InfoWindow
        var mBitmap = BitmapDescriptorFactory.fromResource(R.drawable.bubble)

        //响应点击的OnInfoWindowClickListener
        var listener: OnInfoWindowClickListener? = OnInfoWindowClickListener {
            Toast.makeText(
                this@MainActivity,
                "Click on InfoWindow",
                Toast.LENGTH_LONG
            ).show()
        }
        //构造InfoWindow
        //ll 描述的位置点
        //-100 InfoWindow相对于point在y轴的偏移量
        var mInfoWindow = InfoWindow(mBitmap, lat, -100, listener)
        //显示信息窗在地图上
        mBaiduMap!!.showInfoWindow(mInfoWindow)
    }

    fun addMarker(lat: LatLng) {

        var point = lat
        var bitmap =
            BitmapDescriptorFactory.fromResource(R.drawable.icon_mark_water)
        var option =
            MarkerOptions().position(point).icon(bitmap)
        mBaiduMap!!.addOverlay(option)
    }

    /**
     * 初始化View控件
     * */
    fun initView() {
        mMapView = findViewById<MapView>(R.id.bmapView)
    }

    /**
     * 初始化地图
     */

    fun start() {
        //得到地图实例
        mBaiduMap = mMapView!!.map
        //开启定位图层
        mBaiduMap!!.setMyLocationEnabled(true)
        //声明LocationClient类
        mLocationClient = LocationClient(this)
        //注册监听函数
        mLocationClient!!.registerLocationListener(myLocationListener)
        initLocation()
        /*
        设置地图类型
         */
        //普通地图
        mBaiduMap!!.setMapType(BaiduMap.MAP_TYPE_NORMAL)
        //卫星地图
        //baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
        //空白地图, 基础地图瓦片将不会被渲染。在地图类型中设置为NONE，将不会使用流量下载基础地图瓦片图层。使用场景：与瓦片图层一起使用，节省流量，提升自定义瓦片图下载速度。
        //baiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
        //开启交通图
        mBaiduMap!!.setTrafficEnabled(true)
        val ll = LatLng(25.1918, 110.2440)
        addMarker(ll)
        addInfoWindow(ll)
        clickMap()
//        //用来构造InfoWindow的Button
//        var button = Button(applicationContext)
//        button.setBackgroundResource(R.drawable.bubble)
//        button.setText("自定义文字")
//        //构造InfoWindow
//        //ll 描述的位置点
//        //-100 InfoWindow相对于point在y轴的偏移量
//        var mInfoWindow1 = InfoWindow(button,ll,-200)
//        mBaiduMap!!.showInfoWindow(mInfoWindow1)
    }

    //初始化定位
    private fun initLocation() {
        //通过LocationClientOption()设置LocationClient相关参数
        val option = LocationClientOption()
        //可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.locationMode = LocationClientOption.LocationMode.Hight_Accuracy
        //可选，默认gcj02，设置返回的定位结果坐标系
        option.setCoorType("bd09ll")
        //可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        val span = 1000
        option.setScanSpan(span)
        //可选，设置是否需要地址信息，默认不需要
        option.setIsNeedAddress(true)
        //可选，默认false,设置是否使用gps
        option.isOpenGps = true
        //可选，默认false，设置是否当GPS有效时按照1S/1次频率输出GPS结果
        option.isLocationNotify = true
        //可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationDescribe(true)
        //可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIsNeedLocationPoiList(true)
        //可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        option.setIgnoreKillProcess(false)
        //可选，默认false，设置是否收集CRASH信息，默认收集
        option.SetIgnoreCacheException(false)
        //可选，默认false，设置是否需要过滤GPS仿真结果，默认需要
        option.setEnableSimulateGps(false)
        //可选，默认false，设置是否需要位置描述信息，默认不需要
        //如果开发者需要获得当前点的位置信息，此处必须为true
        option.setIsNeedLocationDescribe(true)
        mLocationClient!!.setLocOption(option)//配置locationClientOption
        //开始定位
        mLocationClient!!.start()
    }

    /**
     * 实现定位监听 位置一旦有所改变就会调用这个方法
     * 可以在这个方法里面获取到定位之后获取到的一系列数据
     */
    private class MyLocationListener(mainActivity: MainActivity) : BDAbstractLocationListener() {
        private var mainActivity: MainActivity

        init {
            this.mainActivity = mainActivity
        }

        override fun onReceiveLocation(location: BDLocation) {
            //定位SDK获取位置后回调
            //获取定位结果
            location.time;    //获取定位时间
            location.locationID;    //获取定位唯一ID，v7.2版本新增，用于排查定位问题
            location.locType;    //获取定位类型
            location.latitude;    //获取纬度信息
            location.longitude;    //获取经度信息
            location.radius;    //获取定位精准度
            location.addrStr;    //获取地址信息
            location.country;    //获取国家信息
            location.countryCode;    //获取国家码
            location.city;    //获取城市信息
            location.cityCode;    //获取城市码
            location.district;    //获取区县信息
            location.street;    //获取街道信息
            location.streetNumber;    //获取街道码
            location.locationDescribe;    //获取当前位置描述信息
            location.poiList;    //获取当前位置周边POI信息
            location.direction  //方向

            location.buildingID;    //室内精准定位下，获取楼宇ID
            location.buildingName;    //室内精准定位下，获取楼宇名称
            location.floor;    //室内精准定位下，获取当前位置所处的楼层信息


            //经纬度
            mainActivity.lat = location.latitude;
            mainActivity.lon = location.longitude;
            //这个判断是为了防止每次定位都重新设置中心点和marker
            if (mainActivity.isFirstLocation) {
                mainActivity.isFirstLocation = false;
                //设置并显示中心点

                setPosition2Center(mainActivity.mBaiduMap!!, location, true)
            }
        }

        /**
         * 设置中心点和添加marker
         *
         * @param map
         * @param bdLocation
         * @param isShowLoc
         */
        fun setPosition2Center(
            map: BaiduMap,
            bdLocation: BDLocation,
            isShowLoc: Boolean
        ) {
            var locData = MyLocationData.Builder()
                .accuracy(bdLocation.radius) // 此处设置开发者获取到的方向信息，顺时针0-360
                .direction(bdLocation.direction)
                .latitude(bdLocation.latitude)
                .longitude(bdLocation.longitude).build()
            map.setMyLocationData(locData)

            if (isShowLoc) {
                var ll = LatLng(bdLocation.latitude, bdLocation.longitude)
                var builder: MapStatus.Builder = MapStatus.Builder()
                builder.target(ll).zoom(18.0f);
                map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
        }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
        //权限是否申请
        if ((PERMISSION.all { checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED }) != true) {
            requestPermissions(PERMISSION, mRuquestode)
        } else {
            start()
        }
        return


    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == mRuquestode) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                start()
            } else {
                Toast.makeText(this@MainActivity, "定位权限未授予！无法定位", Toast.LENGTH_SHORT).show()
            }
            return
        }

    }

    override fun onResume() {
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mMapView!!.onResume()
        super.onResume()

    }

    override fun onPause() {
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView!!.onPause()
        super.onPause()

    }

    override fun onDestroy() {

        mLocationClient!!.stop()
        mBaiduMap!!.setMyLocationEnabled(false)
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mMapView!!.onDestroy()
        mMapView = null;
        super.onDestroy()
    }
}
